package com.zqs.takeredpackage.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.zqs.takeredpackage.entity.RedPackage;
import com.zqs.takeredpackage.entity.User;
import com.zqs.takeredpackage.service.RedPackageService;
import com.zqs.takeredpackage.util.RandomMoneyUtil;
import com.zqs.takeredpackage.util.RedPackageStoreUtil;
import com.zqs.takeredpackage.util.UserStoreUtil;
import com.zqs.takeredpackage.vo.TakerVO;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
public class RedPackageServiceImpl implements RedPackageService {

    private static final UserStoreUtil userStoreUtil = new UserStoreUtil();
    Map<String, ArrayList<String>> userRedPackageKeys = RedPackageStoreUtil.userRedPackageKeys;
    Map<String, ArrayList<TakerVO>> redPackageTakers = RedPackageStoreUtil.redPackageTakers;
    Map<String, RedPackage> userRedPackage = RedPackageStoreUtil.userRedPackage;

    @Override
    public List<RedPackage> list() {
        List<RedPackage> redPackages = userRedPackage.values().stream().toList();
        redPackages.forEach(redPackage -> {
            redPackage.setUsername(userStoreUtil.getUserById(redPackage.getUserId()).getUsername());
        });
        return redPackages;
    }

    @Override
    public ArrayList<RedPackage> myList() {
        ArrayList<String> redIdList = userRedPackageKeys.get((String) StpUtil.getLoginId());
        if (redIdList == null) {
            return null;
        }
        ArrayList<RedPackage> redPackages = new ArrayList<>();
        for (String redId : redIdList) {
            RedPackage redPackage = userRedPackage.get(redId);
            if (redPackage == null) return null;
            redPackages.add(redPackage);
        }
        redPackages.forEach(redPackage -> redPackage.setUsername(userStoreUtil.getUserById(redPackage.getUserId()).getUsername()));
        return redPackages;
    }

    @Override
    public RedPackage get(String redId) {
        return userRedPackage.get(redId);
    }

    @Override
    public SaResult set(int size, BigDecimal money) {
        User user = userStoreUtil.getUserById(StpUtil.getLoginId().toString());
        //判断余额是否满足发红包
        if (user.getMoney().compareTo(money) < 0) {
            return SaResult.error("余额不足！");
        }
        //检验size
        if (size <= 0) {
            return SaResult.error("红包数量不能小于1！");
        }
        if (money.compareTo(BigDecimal.ZERO) <= 0) {
            return SaResult.error("红包金额不能小于0！");
        }
        String key = (String) StpUtil.getLoginId(); //用户指定
        String redId = UUID.randomUUID().toString(); //红包id
        RedPackage redPackage = new RedPackage();
        redPackage.setId(redId);
        redPackage.setUserId(key);
        redPackage.setRemainMoney(money);
        redPackage.setRemainSize(size);
        redPackage.setCreateTime(new Date(System.currentTimeMillis()));
        //存红包
        userRedPackage.put(redId, redPackage);

        if (userRedPackageKeys.containsKey(key)) {
            userRedPackageKeys.get(key).add(redId);
        } else {
            ArrayList<String> keys = new ArrayList<>();
            keys.add(redId);
            userRedPackageKeys.put(key, keys);
        }
        //减余额
        userStoreUtil.updateUserRedPackage(user.getAccount(), money.negate());
        return SaResult.ok("发红包成功！");
    }

    @Override
    public SaResult take(String redId) {
        //判断该用户是否领取过
        if (redPackageTakers.containsKey(redId)) {
            for (TakerVO takerVO : redPackageTakers.get(redId)) {
                if (takerVO.getId().equals(StpUtil.getLoginId().toString())) {
                    return SaResult.error("你已经领取过红包！");
                }
            }
        }
        RedPackage redPackage = userRedPackage.get(redId);
        if(redPackage == null){
            return SaResult.error("红包不存在，请刷新页面");
        }
        try {
            if (redPackage.getRemainSize() <= 0) {
                System.out.println(redPackage.getRemainMoney());
                return SaResult.error("抢红包结束！").setData(BigDecimal.ZERO);
            }
            //开红包的金额
            BigDecimal randomMoney = RandomMoneyUtil.getRandomMoney(redPackage);
            System.out.println(redPackage.getRemainMoney());
            userRedPackage.put(redId, redPackage);
            //记录用户
            User user = userStoreUtil.getUserById(StpUtil.getLoginId().toString());
            TakerVO takerVO = new TakerVO(StpUtil.getLoginId().toString(),
                    user.getUsername()
                    , randomMoney);
            if (redPackageTakers.containsKey(redId)) {
                redPackageTakers.get(redId).add(takerVO);
            } else {
                ArrayList<TakerVO> takers = new ArrayList<>();
                takers.add(takerVO);
                redPackageTakers.put(redId, takers);
            }
            userStoreUtil.updateUserRedPackage(user.getAccount(), randomMoney);
            return SaResult.ok("抢红包成功！").setData(randomMoney);
        } catch (Exception e) {
            e.printStackTrace();
            return SaResult.error("抢红包失败！").set("remainMoney", redPackage.getRemainMoney());
        }
    }

    @Override
    public SaResult takers(String redId) {
        return new SaResult().setData(redPackageTakers.get(redId));
    }

    @Override
    public void cancel(String redId) {
        User user = userStoreUtil.getUserById(StpUtil.getLoginId().toString());
        //回滚红包
        RedPackage redPackage = userRedPackage.get(redId);
        userStoreUtil.updateUserRedPackage(user.getAccount(), redPackage.getRemainMoney());
        //删除大厅红包
        userRedPackage.remove(redId);
        //删除用户红包
        userRedPackageKeys.get(StpUtil.getLoginId().toString())
                .removeIf(redId1 -> redId1.equals(redId));
    }

    @Override
    public ArrayList<User> rank() {
        ArrayList<User> userList = userStoreUtil.getUserList();
        userList.sort((o1, o2) -> o2.getMoney().compareTo(o1.getMoney()));
        return userList;
    }
}
